#! /usr/bin/python3
# -*- coding: UTF-8 -*-
  
'''※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
File Name: Image_Collection.py
Author: GID5564
Description: 图片采集- 网络爬取
Version: 1.0
Created Time: 22/05/24-23:48:56
※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※'''
"""
1. `https://image.baidu.com/search/index`：这是百度图片搜索的主页地址。
2. `?tn=baiduimage`：这个参数表示搜索结果的类型，这里是百度图片。
3. `&ipn=r`：这个参数表示是否显示图片的结果，r表示只显示图片。
4. `&ct=201326592`：这个参数表示搜索结果的分类，201326592表示全部图片。
5. `&cl=2`：这个参数表示搜索结果的排序方式，2表示按照相关性排序。
6. `&lm=-1`：这个参数表示搜索结果的语言，-1表示不限制语言。
7. `&st=-1`：这个参数表示搜索结果的时间，-1表示不限制时间。
8. `&fm=result`：这个参数表示搜索结果的格式，result表示以结果列表的形式展示。
9. `&fr=`：这个参数表示搜索结果的起始位置，这里为空表示从第一个结果开始。
10. `&sf=1`：这个参数表示搜索结果的缩放比例，1表示原始大小。
11. `&fmq=1647837998851_R`：这个参数表示搜索结果的时间戳，用于防止缓存。
12. `&pv=`：这个参数表示搜索结果的预览图，这里为空表示不显示预览图。
13. `&ic=`：这个参数表示搜索结果的图标，这里为空表示不显示图标。
14. `&nc=1`：这个参数表示搜索结果的数量，1表示只显示一个结果。
15. `&z=`：这个参数表示搜索结果的尺寸，这里为空表示不限制尺寸。
16. `&hd=`：这个参数表示搜索结果的清晰度，这里为空表示不限制清晰度。
17. `&latest=`：这个参数表示搜索结果的时间范围，这里为空表示不限制时间范围。
18. `&copyright=`：这个参数表示搜索结果的版权，这里为空表示不限制版权。
19. `&se=1`：这个参数表示搜索结果的扩展选项，1表示启用扩展选项。
20. `&showtab=0`：这个参数表示是否显示标签页，0表示不显示。
21. `&fb=0`：这个参数表示是否显示底部信息，0表示不显示。
22. `&width=`：这个参数表示搜索结果的宽度，这里为空表示不限制宽度。
23. `&height=`：这个参数表示搜索结果的高度，这里为空表示不限制高度。
24. `&face=0`：这个参数表示搜索结果是否包含人脸，0表示不包含。
25. `&istype=2`：这个参数表示搜索结果的类型，2表示图片。
26. `&dyTabStr=MCwzLDIsNiwxLDUsNCw4LDcsOQ%3D%3D`：这个参数表示搜索结果的动态标签，用于显示不同的搜索条件。
27. `&ie=utf-8`：这个参数表示搜索结果的编码方式，utf-8表示使用UTF-8编码。
28. `&sid=`：这个参数表示搜索会话的ID，这里为空表示没有会话ID。
29. `&word=%E7%8B%97%E7%8B%97`：这个参数表示搜索关键词，这里是“狗狗”，是经过URL编码的中文字符串。

"""
import os
import time
import requests
import urllib3
urllib3.disable_warnings()

# 进度条库
from tqdm import tqdm

COOKIES= {
'BDqhfp': '%E7%8B%97%E7%8B%97%26%26NaN-1undefined%26%2618880%26%2621',
'BIDUPSID': '06338E0BE23C6ADB52165ACEB972355B',
'PSTM': '1646905430',
'BAIDUID': '104BD58A7C408DABABCAC9E0A1B184B4:FG=1',
'BDORZ': 'B490B5EBF6F3CD402E515D22BCDA1598',
'H_PS_PSSID': '35836_35105_31254_36024_36005_34584_36142_36120_36032_35993_35984_35319_26350_35723_22160_36061',
'BDSFRCVID': '8--OJexroG0xMovDbuOS5T78igKKHJQTDYLtOwXPsp3LGJLVgaSTEG0PtjcEHMA-2ZlgogKK02OTH6KF_2uxOjjg8UtVJeC6EG0Ptf8g0M5',
'H_BDCLCKID_SF': 'tJPqoKtbtDI3fP36qR3KhPt8Kpby2D62aKDs2nopBhcqEIL4QTQM5p5yQ2c7LUvtynT2KJnz3Po8MUbSj4QoDjFjXJ7RJRJbK6vwKJ5s5h5nhMJSb67JDMP0-4F8exry523ioIovQpn0MhQ3DRoWXPIqbN7P-p5Z5mAqKl0MLPbtbb0xXj_0D6bBjHujtT_s2TTKLPK8fCnBDP59MDTjhPrMypomWMT-0bFH_-5L-l5js56SbU5hW5LSQxQ3QhLDQNn7_JjOX-0bVIj6Wl_-etP3yarQhxQxtNRdXInjtpvhHR38MpbobUPUDa59LUvEJgcdot5yBbc8eIna5hjkbfJBQttjQn3hfIkj0DKLtD8bMC-RDjt35n-Wqxobbtof-KOhLTrJaDkWsx7Oy4oTj6DD5lrG0P6RHmb8ht59JROPSU7mhqb_3MvB-fnEbf7r-2TP_R6GBPQtqMbIQft20-DIeMtjBMJaJRCqWR7jWhk2hl72ybCMQlRX5q79atTMfNTJ-qcH0KQpsIJM5-DWbT8EjHCet5DJJn4j_Dv5b-0aKRcY-tT5M-Lf5eT22-usy6Qd2hcH0KLKDh6gb4PhQKuZ5qutLTb4QTbqWKJcKfb1MRjvMPnF-tKZDb-JXtr92nuDal5TtUthSDnTDMRhXfIL04nyKMnitnr9-pnLJpQrh459XP68bTkA5bjZKxtq3mkjbPbDfn02eCKuj6tWj6j0DNRabK6aKC5bL6rJabC3b5CzXU6q2bDeQN3OW4Rq3Irt2M8aQI0WjJ3oyU7k0q0vWtvJWbbvLT7johRTWqR4enjb3MonDh83Mxb4BUrCHRrzWn3O5hvvhKoO3MA-yUKmDloOW-TB5bbPLUQF5l8-sq0x0bOte-bQXH_E5bj2qRCqVIKa3f',
'BDSFRCVID_BFESS': '8--OJexroG0xMovDbuOS5T78igKKHJQTDYLtOwXPsp3LGJLVgaSTEG0PtjcEHMA-2ZlgogKK02OTH6KF_2uxOjjg8UtVJeC6EG0Ptf8g0M5',
'H_BDCLCKID_SF_BFESS': 'tJPqoKtbtDI3fP36qR3KhPt8Kpby2D62aKDs2nopBhcqEIL4QTQM5p5yQ2c7LUvtynT2KJnz3Po8MUbSj4QoDjFjXJ7RJRJbK6vwKJ5s5h5nhMJSb67JDMP0-4F8exry523ioIovQpn0MhQ3DRoWXPIqbN7P-p5Z5mAqKl0MLPbtbb0xXj_0D6bBjHujtT_s2TTKLPK8fCnBDP59MDTjhPrMypomWMT-0bFH_-5L-l5js56SbU5hW5LSQxQ3QhLDQNn7_JjOX-0bVIj6Wl_-etP3yarQhxQxtNRdXInjtpvhHR38MpbobUPUDa59LUvEJgcdot5yBbc8eIna5hjkbfJBQttjQn3hfIkj0DKLtD8bMC-RDjt35n-Wqxobbtof-KOhLTrJaDkWsx7Oy4oTj6DD5lrG0P6RHmb8ht59JROPSU7mhqb_3MvB-fnEbf7r-2TP_R6GBPQtqMbIQft20-DIeMtjBMJaJRCqWR7jWhk2hl72ybCMQlRX5q79atTMfNTJ-qcH0KQpsIJM5-DWbT8EjHCet5DJJn4j_Dv5b-0aKRcY-tT5M-Lf5eT22-usy6Qd2hcH0KLKDh6gb4PhQKuZ5qutLTb4QTbqWKJcKfb1MRjvMPnF-tKZDb-JXtr92nuDal5TtUthSDnTDMRhXfIL04nyKMnitnr9-pnLJpQrh459XP68bTkA5bjZKxtq3mkjbPbDfn02eCKuj6tWj6j0DNRabK6aKC5bL6rJabC3b5CzXU6q2bDeQN3OW4Rq3Irt2M8aQI0WjJ3oyU7k0q0vWtvJWbbvLT7johRTWqR4enjb3MonDh83Mxb4BUrCHRrzWn3O5hvvhKoO3MA-yUKmDloOW-TB5bbPLUQF5l8-sq0x0bOte-bQXH_E5bj2qRCqVIKa3f',
'indexPageSugList': '%5B%22%E7%8B%97%E7%8B%97%22%5D',
'cleanHistoryStatus': '0',
'BAIDUID_BFESS': '104BD58A7C408DABABCAC9E0A1B184B4:FG=1',
'BDRCVFR[dG2JNJb_ajR]': 'mk3SLVN4HKm',
'BDRCVFR[-pGxjrCMryR]': 'mk3SLVN4HKm',
'ab_sr': '1.0.1_Y2YxZDkwMWZkMmY2MzA4MGU0OTNhMzVlNTcwMmM2MWE4YWU4OTc1ZjZmZDM2N2RjYmVkMzFiY2NjNWM4Nzk4NzBlZTliYWU0ZTAyODkzNDA3YzNiMTVjMTllMzQ0MGJlZjAwYzk5MDdjNWM0MzJmMDdhOWNhYTZhMjIwODc5MDMxN2QyMmE1YTFmN2QyY2M1M2VmZDkzMjMyOThiYmNhZA==',
'delPer': '0',
'PSINO': '2',
'BA_HECTOR': '8h24a024042g05alup1h3g0aq0q',
}
# 定义一个字典，用于存储HTTP请求的头部信息
HEADERS= {
'Connection': 'keep-alive', #保持连接状态
'sec-ch-ua': '" Not;A Brand";v="99", "Google Chrome";v="97", "Chromium";v="97"', #用户代理字符串
'Accept': 'text/plain, */*; q=0.01', # 接受的内容类型
'X-Requested-With': 'XMLHttpRequest', # 表示请求是通过
'sec-ch-ua-mobile': '?0', # 是否为移动设备
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36', # 用户代理字符串
'sec-ch-ua-platform': '"macOS"', # 操作系统平台
'Sec-Fetch-Site': 'same-origin', # 请求来源站点
'Sec-Fetch-Mode': 'cors', # 请求模式
'Sec-Fetch-Dest': 'empty', # 请求目标
'Referer': 'https://image.baidu.com/search/index?tn=baiduimage&ipn=r&ct=201326592&cl=2&lm=-1&st=-1&fm=result&fr=&sf=1&fmq=1647837998851_R&pv=&ic=&nc=1&z=&hd=&latest=&copyright=&se=1&showtab=0&fb=0&width=&height=&face=0&istype=2&dyTabStr=MCwzLDIsNiwxLDUsNCw4LDcsOQ%3D%3D&ie=utf-8&sid=&word=%E7%8B%97%E7%8B%97', # 引用页面的URL
'Accept-Language': 'zh-CN,zh;q=0.9',# 接受的语言
}


URL='https://image.baidu.com/search/acjson'


def _craw_single_class(url,headers,cookies,keyword, DOWNLOAD_NUM = 200):
    """
    爬取图片
    :param keyword:str ,下载关键词
    :param DOWNLOAD_NUM:int，下载数量
    :param url: str, 请求的目标网址
    :param headers: dict, 请求头信息，默认为None
    #:param params: dict, 请求参数，默认为None
    :param cookies: dict, 请求携带的cookie信息，默认为None
    :return: response: requests.Response, 请求响应对象
    """
    

    if not os.path.exists('dataset/'+keyword):
        os.makedirs('dataset/{}'.format(keyword))
        print('保存目录：dataset/{}'.format(keyword))
    count = 1
    
    with tqdm(total=DOWNLOAD_NUM, position=0, leave=True,colour="green",desc=keyword) as pbar:
        
        # 爬取第几张
        num = 0

        # 是否继续爬取
        FLAG = True

        while FLAG:
            page = 30 * count
            # 定义一个名为params的元组，用于存储搜索参数，https://image.baidu.com/search/index?tn=baiduimage&ipn=r&ct=201326592&cl=2&lm=-1&st=-1&fm=result&fr=&sf=1&fmq=1647837998851_R&pv=&ic=&nc=1&z=&hd=&latest=&copyright=&se=1&showtab=0&fb=0&width=&height=&face=0&istype=2&dyTabStr=MCwzLDIsNiwxLDUsNCw4LDcsOQ%3D%3D&ie=utf-8&sid=&word=%E7%8B%97%E7%8B%97
            params = (
    ('tn', 'resultjson_com'),  #这个参数表示搜索结果的类型，此为resultjson_com
    ('logid', '12508239107856075440'),  # 设置日志ID
    ('ipn', 'rj'),  # 设置IPN为rj
    ('ct', '201326592'),  # 设置CT为201326592
    ('is', ''),  # 设置IS为空
    ('fp', 'result'),  # 设置FP为result
    ('fr', ''),  # 设置FR为空
    ('word', f'{keyword}'),  # 设置搜索关键词
    ('queryWord', f'{keyword}'),  # 设置查询关键词
    ('cl', '2'),  # 设置CL为2
    ('lm', '-1'),  # 设置LM为-1
    ('ie', 'utf-8'),  # 设置IE为utf-8
    ('oe', 'utf-8'),  # 设置OE为utf-8
    ('adpicid', ''),  # 设置广告图片ID为空
    ('st', '-1'),  # 设置ST为-1
    ('z', ''),  # 设置Z为空
    ('ic', ''),  # 设置IC为空
    ('hd', ''),  # 设置HD为空
    ('latest', ''),  # 设置latest为空
    ('copyright', ''),  # 设置版权信息为空
    ('s', ''),  # 设置S为空
    ('se', ''),  # 设置SE为空
    ('tab', ''),  # 设置TAB为空
    ('width', ''),  # 设置宽度为空
    ('height', ''),  # 设置高度为空
    ('face', '0'),  # 设置面部识别为0
    ('istype', '2'),  # 设置ISTYPE为2
    ('qc', ''),  # 设置QC为空
    ('nc', '1'),  # 设置NC为1
    ('expermode', ''),  # 设置实验模式为空
    ('nojc', ''),  # 设置NOJC为空
    ('isAsync', ''),  # 设置异步为空
    ('pn', f'{page}'),  # 设置分页参数，当前页数为page
    ('rn', '30'),  # 设置每页显示结果数量为30
    ('gsm', '1e'),  # 设置GSM为1e
    ('1647838001666', ''),  # 设置时间戳为空
)

            response = requests.get(url, headers=headers, params=params, cookies=cookies)
            if response.status_code == 200:
                try:
                    json_data = response.json().get("data")

                    if json_data:
                        for x in json_data:
                            type = x.get("type")
                            if type not in ["gif"]:
                                img = x.get("thumbURL")
                                fromPageTitleEnc = x.get("fromPageTitleEnc")
                                try:
                                    resp = requests.get(url=img, verify=False)
                                    time.sleep(1)
                                    # print(f"链接 {img}")

                                    # 保存文件名
                                    file_save_path = f'dataset/{keyword}/{num}.{type}'
                                    with open(file_save_path, 'wb') as f:                                    
                                        f.write(resp.content)
                                        f.flush()
                                        num += 1
                                        pbar.update(1) # 进度条更新

                                    # 爬取数量达到要求
                                    if num > DOWNLOAD_NUM:
                                        FLAG = False
                                        print('{} 张图像爬取完毕'.format(num))
                                        break

                                except Exception:
                                    pass
                except:
                    pass
            else:
                break

            count += 1


def extract_params(url: str) -> tuple:
    """
    提取url中？后的以&分隔的字符串形成元组，再根据元组中每个元素以=分隔的字符串形成子元组
    :param url: str, 输入的url
    :return: tuple, 返回一个包含子元组的元组
    """
    # 提取？后的字符串
    query_string = url.split('?')[-1]
    
    # 以&分隔字符串形成元组
    params = query_string.split('&')
    
    # 根据元组中每个元素以=分隔的字符串形成子元组
    result = tuple((param.split('=') for param in params))
    
    return result



#采集数据
def collecte_data(keyword,size=200):
    """
    爬取图片
    :param keyword:str ,下载关键词
    :param DOWNLOAD_NUM:int，下载数量
    """
    _craw_single_class(URL,HEADERS,COOKIES,keyword, size)





class_list = ['黄瓜','南瓜','冬瓜','木瓜']
for each in class_list:
    collecte_data(each,10)






















